﻿#region Using directives

using System;
using System.Collections.Generic;
using System.Text;

#endregion

namespace AutoFormatter
{
    public abstract class HtmlType
    {
        private readonly string tag, closingtag;
        /// <summary>
        /// The start of a rtf keyword that represented by this type
        /// </summary>
        private readonly string kw;
        private int kwnumberindex;
        /// <summary>
        /// The finish of <see cref="kw"/>
        /// </summary>
        protected string kwclose;

        protected HtmlType(string htmltag, string rtfkw):this(htmltag,rtfkw,null) { }
        protected HtmlType(string htmltag, string rtfkw, string rtfkwclose)
        {
            tag = htmltag;
            kw = rtfkw;
            kwnumberindex = kw.Length;
            kwclose = rtfkwclose;
            if (kwclose == null) kwclose = kw + "0";
            int i = tag.IndexOf(' ');
            closingtag = i == -1 ? tag : tag.Substring(0, i);
        }
        /// <summary>
        /// Indicates if the current tag is open
        /// </summary>
        public bool IsOpen = false;

        /// <summary>
        /// Closes the html tag
        /// </summary>
        public void Close(StringBuilder sb)
        {
            if (IsOpen)
            {
                sb.Append("</")
                 .Append(closingtag)
                 .Append(">");
                IsOpen = false;
                value = 0;
            }
        }
        protected int value = 0;
        public bool CheckChanged(ref string kw,StringBuilder sb)
        {
            if (kw == kwclose)
                Close(sb);
            else if (kw.StartsWith(this.kw))
            {
                int v;
                if (kw.Length == this.kw.Length)
                    v = -1;
                else if (char.IsNumber(kw[kwnumberindex]))
                    v = int.Parse(kw.Substring(this.kw.Length));
                else
                    return false;

                if (v != value)
                {
                    Close(sb);
                    value = v;

                    sb.Append("<");
                    sb.Append(tag);
                    Addvalue(sb);
                    sb.Append(">");
                    IsOpen = true;
                }
            }
            else
                return false;
            return true;
        }

        protected virtual void Addvalue(StringBuilder sb)
        {
        }

        #region static collection
        /// <summary>
        /// Get All present html types
        /// </summary>
        public static List<HtmlType> GetHtmlTypes(StringBuilder sb)
        {
            List<HtmlType> htmltypes = new List<HtmlType>();
            foreach (Type t in typeof(frmMain).Assembly.GetTypes())
            {
                if (t.IsSubclassOf(typeof(HtmlType))
                    && !t.IsAbstract
                    && t.GetConstructor(Type.EmptyTypes) != null
                    )
                {                    
                    HtmlType ht = Activator.CreateInstance(t) as HtmlType;
                    htmltypes.Add(ht);
                }
            }
            return htmltypes;
        }

        #endregion
    }
}
